package com.zy.openchat.core.model.message;

import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import com.chad.library.adapter.base.entity.MultiItemEntity;
import com.google.gson.Gson;
import com.ja.openchat.R;
import com.zy.openchat.App;
import com.zy.openchat.core.manager.TelegramManager;
import com.zy.openchat.core.model.audio.AudioInfo;
import com.zy.openchat.core.model.voice.VoiceInfo;
import com.zy.openchat.core.model.call.LocalCallInfo;
import com.zy.openchat.core.model.file.FileInfo;
import com.zy.openchat.core.model.photo.PhotoSizeInfo;
import com.zy.openchat.core.model.redpacket.RP_Msg;
import com.zy.openchat.core.model.redpacket.RP_Pick_Msg;
import com.zy.openchat.core.model.redpacket.RedPacketInfo;
import com.zy.openchat.core.model.remittance.RemittanceInfo;
import com.zy.openchat.core.model.user.UserInfo;
import com.zy.openchat.core.model.video.VideoInfo;
import com.zy.openchat.util.Common;
import com.zy.openchat.util.DateHelper;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import java.util.ArrayList;
import java.util.List;

import me.goldze.mvvmhabit.utils.MultiLanguageUtil;

public class MessageInfo implements Parcelable , MultiItemEntity {
    //消息是否已读判断id<=chatInfo.last_read_outbox_message_id
    public long id;
    //发送者userid
    public MessageSendUser sender;
    //会话id
    public long chat_id;
    //产生日期
    public long date;
    //是否为发出的消息，兼容我的收藏，请使用isOutgoing()方法判断
    private boolean is_outgoing;

    public long reply_in_chat_id;
    public long reply_to_message_id;
    public int ttl;
    public double ttl_expires_in;

    public String buildVideoRequest(){
        String requestUrl = String.format("http://127.0.0.1:39961/%d.mp4",getVideoFileId());
//        HttpProxyCacheServer.clientsLocalPathMap.put(requestUrl,getVideo().localVideoPath());
        return requestUrl;
    }

    private MessageInfo replyMessageInfo;

    private HtmlDocumentInfo htmlDocumentInfo;

    public HtmlDocumentInfo getHtmlDocumentInfo() {
        return htmlDocumentInfo;
    }

    public void setHtmlDocumentInfo(HtmlDocumentInfo htmlDocumentInfo) {
        this.htmlDocumentInfo = htmlDocumentInfo;
    }

    @Override
    public int getItemType() {
        return messageType.ordinal();
    }

    public MessageInfo getReplyMessageInfo() {
        return replyMessageInfo;
    }

    public void setReplyMessageInfo(MessageInfo replyMessageInfo) {
        this.replyMessageInfo = replyMessageInfo;
    }

    public boolean isOutgoing() {
        if (isFromMyFovChat()) {
            return true;
        }
        return is_outgoing;
    }

    public void setIs_outgoing(boolean is_outgoing) {
        this.is_outgoing = is_outgoing;
    }

    //
    public boolean is_channel_post;
    //是否存在未读的@
    public boolean contains_unread_mention;

    //消息具体内容
    public MessageContent content;

    public ReplyMarkupInfo reply_markup;


    //MessageSendingState - 发送消息当前状态
    private MessageSendingState sending_state;

    public boolean updateFileInfo(FileInfo fileInfo){
        if(fileInfo==null||content==null){
            return false;
        }
        if(content!=null&&content.photo!=null){
            if(content.photo.updatePhotoFile(fileInfo)){
                return true;
            }
        }
        if(content!=null&&content.video!=null){
            if(content.video.video.id == fileInfo.id){
                content.video.updateVideoFile(fileInfo);
                return true;
            }
        }
        if(content!=null&&content.animation!=null){
            if(content.animation.animation.id == fileInfo.id){
                content.animation.updateAnimationFile(fileInfo);
                return true;
            }
        }
        if(content!=null&&content.audio!=null){
            if(content.audio.audio.id == fileInfo.id){
                content.audio.updateFile(fileInfo);
                return true;
            }
        }
        if(content!=null&&content.voice_note!=null){
            if(content.voice_note.voice.id == fileInfo.id){
                content.voice_note.updateFile(fileInfo);
                return true;
            }
        }
        if(content!=null&&content.document!=null){
            if(content.document.document.id == fileInfo.id){
                content.document.updateFile(fileInfo);
                return true;
            }
        }

        return false;
    }

    public String getRemoteFileId(){
        if(content==null){
            return null;
        }
        if(content!=null&&content.photo!=null){
            return content.photo.getRemotePhotoFileId();
        }
        if(content!=null&&content.video!=null){
            return content.video.getRemoteVideoFileId();
        }
        if(content!=null&&content.animation!=null){
            return content.animation.getRemoteAnimationFileId();
        }
        if(content!=null&&content.audio!=null){
            return content.audio.getRemoteFileId();
        }
        if(content!=null&&content.voice_note!=null){
            return content.voice_note.getRemoteFileId();
        }
        if(content!=null&&content.document!=null){
            return content.document.getRemoteFileId();
        }
        return null;
    }

    public int getUploadingProgress(){
       return  (int)Math.ceil(getUploadingRate()*100);
    }

    public double getUploadingRate(){
        long totalSize = 0;
        long uploadedSize = 0;
        if(content.video!=null&&content.video.video!=null&&content.video.video.remote!=null){
            totalSize = content.video.totalSize();
            uploadedSize = content.video.video.remote.uploaded_size;
        }
        if(content.animation!=null&&content.animation.animation!=null&&content.animation.animation.remote!=null){
            totalSize = totalSize + content.animation.totalAnimationSize();
            uploadedSize = uploadedSize + content.animation.animation.remote.uploaded_size;
        }
        if(content.audio!=null&&content.audio.audio!=null&&content.audio.audio.remote!=null){
            totalSize = totalSize + content.audio.totalSize();
            uploadedSize = uploadedSize + content.audio.audio.remote.uploaded_size;
        }
        if(content.voice_note!=null&&content.voice_note.voice!=null&&content.voice_note.voice.remote!=null){
            totalSize = totalSize + content.voice_note.totalSize();
            uploadedSize = uploadedSize + content.voice_note.voice.remote.uploaded_size;
        }
        if(content.document!=null&&content.document.document!=null&&content.document.document.remote!=null){
            totalSize = totalSize + content.document.totalSize();
            uploadedSize = uploadedSize + content.document.document.remote.uploaded_size;
        }
        if(content.photo!=null){
            totalSize = totalSize + content.photo.totalSize();
            uploadedSize = uploadedSize + content.photo.uploadedSize();
        }
        if(totalSize<=0){
            return 0;
        }
        return uploadedSize/(double)totalSize;
    }

    //是否已读
    public boolean isRead() {
        ChatInfo chat = TelegramManager.getTelegramManager().getTgData().chatInfo(chat_id);
        if (chat != null) {
            return id <= chat.last_read_outbox_message_id;
        }
        return true;
    }

    public MessageSendingState getSending_state(){
        return sending_state;
    }

    /**
     * 是否来自我的收藏
     *
     * @return
     */
    public boolean isFromMyFovChat() {
        return chat_id == UserInfo.getUserInfo().id;
    }

    //消息发送状态
    public TelegramManager.MessageSendState sendState() {
        if (is_outgoing && sending_state != null) {
            return sending_state.sendState();
        }
        return TelegramManager.MessageSendState.MessageSendState_Success;
    }

    //消息类型
    public TelegramManager.MessageType messageType;

    /**
     * 图片类型有效-获取图片文件id - 消息时使用
     */
    public long getMessagePhotoFileId() {
        if (content != null && content.photo != null) {
            PhotoSizeInfo size = content.photo.messagePhoto();
            if (size != null && size.photo != null) {
                return size.photo.id;
            }
        }
        return 0;
    }

    /**
     * 图片类型有效-获取图片对象，包括宽高和本地远程文件 - 消息时使用
     */
    public PhotoSizeInfo getMessagePhoto() {
        if (content != null && content.photo != null) {
            return content.photo.messagePhoto();
        }
        return null;
    }

    /**
     * 图片类型有效-获取图片文件 - 消息时使用
     */
    public FileInfo getMessagePhotoFile() {
        if (content != null && content.photo != null) {
            PhotoSizeInfo size = content.photo.messagePhoto();
            if (size != null && size.photo != null) {
                return size.photo;
            }
        }
        return null;
    }

    /**
     * 更新图片消息文件信息 - 消息时使用
     */
    public void updateMessagePhotoFile(FileInfo file) {
        if (content != null && content.photo != null) {
            PhotoSizeInfo size = content.photo.messagePhoto();
            size.photo = file;
        }
    }

    /**
     * 图片是否下载 - 消息时使用
     */
    public boolean isMessagePhotoFileDownloaded() {
        PhotoSizeInfo size = getMessagePhoto();
        if (size != null) {
            return size.isPhotoDownloaded();
        }
        return false;
    }

    /**
     * 获取图片本地下载地址 - 消息时使用
     */
    public String messagePhotoLocalPath() {
        PhotoSizeInfo size = getMessagePhoto();
        if (size != null && size.photo != null && size.photo.local != null && size.photo.local.isExist()) {
            return size.photo.local.path;
        }
        return null;
    }

    public Boolean isMessagePhotoDownloaded() {
        if (content != null && content.photo != null) {
            PhotoSizeInfo size = content.photo.messagePhoto();
            if (size != null) {
                return size.isPhotoDownloaded();
            }
        }
        return false;
    }

    /**
     * 图片类型有效-获取图片文件id - 预览时使用
     */
    public long getPreviewPhotoFileId() {
        if (content != null && content.photo != null) {
            PhotoSizeInfo size = content.photo.previewPhoto();
            if (size != null && size.photo != null) {
                return size.photo.id;
            }
        }
        return 0;
    }

    /**
     * 图片类型有效-获取预览图片对象，包括宽高和本地远程文件 - 预览时使用
     */
    public PhotoSizeInfo getPreviewPhoto() {
        if (content != null && content.photo != null) {
            return content.photo.previewPhoto();
        }
        return null;
    }

    /**
     * 图片类型有效-获取图片文件 - 预览时使用
     */
    public FileInfo getPreviewPhotoFile() {
        if (content != null && content.photo != null) {
            PhotoSizeInfo size = content.photo.previewPhoto();
            if (size != null && size.photo != null) {
                return size.photo;
            }
        }
        return null;
    }


    /**
     * 更新图片消息文件信息 - 预览时使用
     */
    public void updatePreviewPhotoFile(FileInfo file) {
        if (content != null && content.photo != null) {
            PhotoSizeInfo size = content.photo.previewPhoto();
            size.photo = file;
        }
    }

    /**
     * 预览图片是否下载 - 预览时使用
     */
    public boolean isPreviewPhotoFileDownloaded() {
        PhotoSizeInfo size = getPreviewPhoto();
        if (size != null) {
            return size.isPhotoDownloaded();
        }
        return false;
    }

    /**
     * 获取预览图片本地下载地址 - 预览时使用
     */
    public String previewPhotoLocalPath() {
        PhotoSizeInfo size = getPreviewPhoto();
        if (size != null && size.photo != null && size.photo.local != null && size.photo.local.isExist()) {
            return size.photo.local.path;
        }
        return null;
    }


    public boolean isDocumentFileDownloaded() {
        if (content != null && content.document != null) {
            return content.document.isFileDownloaded();
        }
        return false;
    }

    /**
     * 视频类型有效-获取视频文件id
     */
    public long getVideoFileId() {
        if (content != null && content.video != null && content.video.video != null) {
            return content.video.video.id;
        }
        return 0;
    }

    public long getAnimationFileId() {
        if (content != null && content.animation != null && content.animation.animation != null) {
            return content.animation.animation.id;
        }
        return 0;
    }

    public long getVideoThumbnailFileId() {
        if (content != null && content.video != null && content.video.thumbnail != null && content.video.thumbnail.file != null) {
            return content.video.thumbnail.file.id;
        }
        return 0;
    }

    /**
     * 视频类型有效，包括宽高、时长和本地远程文件-获取视频对象
     */
    public VideoInfo getVideo() {
        if (content != null && content.video != null) {
            return content.video;
        }
        return null;
    }

    public VideoInfo getAnimation() {
        if (content != null && content.animation != null) {
            return content.animation;
        }
        return null;
    }

    /**
     * 视频类型有效-获取视频文件
     */
    public FileInfo getVideoFile() {
        if (content != null && content.video != null && content.video.video != null) {
            return content.video.video;
        }
        return null;
    }


    public FileInfo getAnimationFile() {
        if (content != null && content.animation != null && content.animation.animation != null) {
            return content.animation.animation;
        }
        return null;
    }


    public String getRemoteAnimationFileId() {
        if (content != null && content.animation != null && content.animation.animation != null&& content.animation.animation.remote != null) {
            return content.animation.animation.remote.id;
        }
        return null;
    }

    /**
     * 更新视频消息文件信息
     */
    public void updateVideoFile(FileInfo file) {
        if (content != null && content.video != null && content.video.video != null) {
            content.video.video = file;
        }
    }

    public void updateDocumentFile(FileInfo file) {
        if (content != null && content.document != null && content.document.document != null) {
            content.document.document = file;
        }
    }

    public void updateAnimationFile(FileInfo file) {
        if (content != null && content.animation != null && content.animation.animation != null) {
            content.animation.animation = file;
        }
    }

    /**
     * 视频是否下载
     */
    public boolean isVideoFileDownloaded() {
        VideoInfo v = getVideo();
        if (v != null) {
            return v.isVideoDownloaded();
        }
        return false;
    }

    public boolean isAnimationDownloaded() {
        VideoInfo v = getAnimation();
        if (v != null) {
            return v.isAnimationDownloaded();
        }
        return false;
    }

    /**
     * 获取视频本地下载地址
     */
    public String videoLocalPath() {
        VideoInfo v = getVideo();
        if (v != null) {
            return v.localVideoPath();
        }
        return null;
    }

    /**
     * 语音类型有效-获取语音文件id
     */
    public long getAudioFileId() {
        if (content != null && content.audio != null && content.audio.audio != null) {
            return content.audio.audio.id;
        }
        return 0;
    }

    /**
     * 语音类型有效-获取语音
     */
    public AudioInfo getAudio() {
        if (content != null && content.audio != null) {
            return content.audio;
        }
        return null;
    }

    /**
     * 语音类型有效-获取语音文件
     */
    public FileInfo getAudioFile() {
        if (content != null && content.audio != null && content.audio.audio != null) {
            return content.audio.audio;
        }
        return null;
    }

    /**
     * 更新语音消息文件信息
     */
    public void updateAudioFile(FileInfo file) {
        if (content != null && content.audio != null && content.audio.audio != null) {
            content.audio.audio = file;
        }
    }

    /**
     * 语音是否下载
     */
    public boolean isAudioFileDownloaded() {
        AudioInfo a = getAudio();
        if (a != null) {
            return a.isAudioDownloaded();
        }
        return false;
    }

    /**
     * 获取语音本地下载地址
     */
    public String audioLocalPath() {
        AudioInfo a = getAudio();
        if (a != null) {
            return a.localAudioPath();
        }
        return null;
    }

    // pc voice
    /**
     * 语音类型有效-获取语音文件id
     */
    public long getVoiceFileId() {
        if (content != null && content.voice_note != null && content.voice_note.voice != null) {
            return content.voice_note.voice.id;
        }
        return 0;
    }

    /**
     * 语音类型有效-获取语音
     */
    public VoiceInfo getVoice() {
        if (content != null && content.voice_note != null) {
            return content.voice_note;
        }
        return null;
    }

    /**
     * 语音类型有效-获取语音文件
     */
    public FileInfo getVoiceFile() {
        if (content != null && content.voice_note != null && content.voice_note.voice != null) {
            return content.voice_note.voice;
        }
        return null;
    }

    /**
     * 更新语音消息文件信息
     */
    public void updateVoiceFile(FileInfo file) {
        if (content != null && content.voice_note != null && content.voice_note.voice != null) {
            content.voice_note.voice = file;
        }
    }

    /**
     * 语音是否下载
     */
    public boolean isVoiceFileDownloaded() {
        VoiceInfo a = getVoice();
        if (a != null) {
            return a.isAudioDownloaded();
        }
        return false;
    }

    /**
     * 获取语音本地下载地址
     */
    public String voiceLocalPath() {
        VoiceInfo a = getVoice();
        if (a != null) {
            return a.localAudioPath();
        }
        return null;
    }

    //是否提示类消息
    public boolean isTipMessage() {
        if (content != null) {
            if ("messageBasicGroupChatCreate".equals(content.type) || "messageSupergroupChatCreate".equals(content.type)) {
                //群组创建
                return true;
            }
            if ("messageChatAddMembers".equals(content.type)) {
                //群组添加成员
                return true;
            }
            if ("messageChatDeleteMember".equals(content.type)) {
                //群组成员移除
                return true;
            }
            if ("messageChatChangeTitle".equals(content.type)) {
                //修改会话标题
                return true;
            }
            if ("messageChatChangePhoto".equals(content.type)) {
                //修改会话头像
                return true;
            }
        }
        switch (messageType) {
            case MessageType_Text:
            case MessageType_Text_AudioAVideo_Done:
            case MessageType_Text_New_Rp:
            case MessageType_Text_Got_Tm:
            case MessageType_Text_New_Tm:
            case MessageType_Text_Refund_Tm:
            case MessageType_Photo:
            case MessageType_Video:
            case MessageType_Document:
            case MessageType_Audio:
            case MessageType_Voice_Note:
            case MessageType_Location:
            case MessageType_Pinned:
                return false;
            case MessageType_Text_Got_Rp:
                return true;
            case MessageType_Text_Screenshot:
                return true;
            case MessageType_Text_BeFriend:
            case MessageType_Contact_Registered:
            case MessageType_Group_Kick:
                return true;
            default:
                return true;
        }
    }

    @SuppressLint("DefaultLocale")
    @Override
    public String toString() {
        if(messageType == null){
            messageType = TelegramManager.MessageType.MessageType_Text;
        }
        if (content != null) {
            if("messageChatJoinByLink".equals(content.type)){
                if(UserInfo.getUserInfo(sender_user_id())!=null){
                    return String.format(App.getInstanse().getString(R.string.sb_joined_group_link),UserInfo.getUserInfo(sender_user_id()).displayName());
                }else{
                    return "";
                }
            }
            if ("messageBasicGroupChatCreate".equals(content.type) || "messageSupergroupChatCreate".equals(content.type)) {
                //群组创建
                if (sender_user_id() == UserInfo.getUserInfo().id) {
                    return String.format(App.getInstanse().getString(R.string.created_group_at_time), DateHelper.getMessageFullDisplayTime(date * 1000, false));
                } else {
                    if(sender_user_id()==0){
                        return String.format(App.getInstanse().getString(R.string.person_created_group_at_time), DateHelper.getMessageFullDisplayTime(date * 1000, false));
                    }else{
                        UserInfo userInfo = UserInfo.getUserInfo(sender_user_id());
                        return String.format(App.getInstanse().getString(R.string.sb_created_group_at_time), userInfo==null?sender_user_id():userInfo.displayName(),DateHelper.getMessageFullDisplayTime(date * 1000, false));
                    }

                }
            }
            if ("messageChatAddMembers".equals(content.type)) {
                //群组添加成员
                StringBuffer memberStr = new StringBuffer();
                List<Long> userIds = new ArrayList<>();
                if (content.member_user_ids != null) {
                    for (long userId : content.member_user_ids) {
                        userIds.add(userId);
                        UserInfo user = TelegramManager.getTelegramManager().getTgData().contactInfo(userId);
                        if (user != null) {
                            if (memberStr.length() > 0) {
                                memberStr.append("、");
                                memberStr.append(user.displayName());
                            } else {
                                memberStr.append(user.displayName());
                            }
                        }
                    }
                }
                if (sender_user_id() == UserInfo.getUserInfo().id) {
                    if(userIds.size()==1&&userIds.get(0) == UserInfo.getUserInfo().id){
                        return String.format(App.getInstanse().getString(R.string.i_join_the_group), memberStr);
                    }else{
                        return String.format(App.getInstanse().getString(R.string.i_invited_sb_group), memberStr);
                    }

                } else {
                    UserInfo user = TelegramManager.getTelegramManager().getTgData().contactInfo(sender_user_id());
                    if (user != null) {
                        if (memberStr.toString().equals(user.displayName())){
                            return String.format(App.getInstanse().getString(R.string.sb_joined_group), user.displayName());
                        }else {
                            return String.format(App.getInstanse().getString(R.string.sb_invited_sb_to_group), user.displayName(), memberStr);
                        }
                    } else {
                        return String.format(App.getInstanse().getString(R.string.sb_invited_group), memberStr);
                    }
                }
            }
            if ("messageChatDeleteMember".equals(content.type)) {
                //群组成员移除
                if (content.user_id == UserInfo.getUserInfo().id) {
                    if (sender_user_id() == UserInfo.getUserInfo().id) {
                        return App.getInstanse().getString(R.string.you_been_removed_from_group);
                    } else {
                        return App.getInstanse().getString(R.string.you_were_removed_from_group);
                    }
                } else {
                    UserInfo user = TelegramManager.getTelegramManager().getTgData().contactInfo(content.user_id);
                    if (user != null) {
                        if (sender_user_id() == content.user_id) {
                            return String.format(App.getInstanse().getString(R.string.sb_lefted_group), user.displayName());
                        } else {
                            return String.format(App.getInstanse().getString(R.string.sb_removed_from_group), user.displayName());
                        }
                    } else {
                        if (sender_user_id() == content.user_id) {
                            return String.format(String.format(App.getInstanse().getString(R.string.sb_lefted_group),"[user_%d]"), content.user_id);
                        } else {
                            return String.format(String.format(App.getInstanse().getString(R.string.sb_removed_from_group),"[user_%d]"), content.user_id);
                        }
                    }
                }
            }
            if ("messageChatChangeTitle".equals(content.type)) {
                //修改会话标题
                if (sender_user_id() == UserInfo.getUserInfo().id) {
                    return String.format(App.getInstanse().getString(R.string.you_changed_group_name_to_so), content.title);
                } else {
                    UserInfo user = TelegramManager.getTelegramManager().getTgData().contactInfo(sender_user_id());
                    if (user != null) {
                        return String.format(App.getInstanse().getString(R.string.sb_changed_group_name_to_so), user.displayName(), content.title);
                    } else {
                        return String.format(App.getInstanse().getString(R.string.group_name_changed_so), content.title);
                    }
                }
            }
            if ("messageChatChangePhoto".equals(content.type)) {
                //修改会话头像
                if (sender_user_id() == UserInfo.getUserInfo().id) {
                    return App.getInstanse().getString(R.string.you_edited_group_avatar);
                } else {
                    UserInfo user = TelegramManager.getTelegramManager().getTgData().contactInfo(sender_user_id());
                    if (user != null) {
                        return String.format(App.getInstanse().getString(R.string.so_modified_group_avatar), user.displayName());
                    } else {
                        return App.getInstanse().getString(R.string.group_avatar_modified);
                    }
                }
            }
        }
        switch (messageType) {
            case MessageType_Text:
            case MessageType_Text_AudioAVideo_Done:
            case MessageType_Text_New_Rp:
            case MessageType_Text_Got_Rp:
            case MessageType_Text_Got_Tm:
            case MessageType_Text_New_Tm:
            case MessageType_Text_Refund_Tm:
            case MessageType_Group_Kick:
                return textTypeContent;
            case MessageType_Photo:
                return String.format("[%s]",App.getInstanse().getString(R.string.image_text));
            case MessageType_Animation:
                return String.format("[%s]",App.getInstanse().getString(R.string.gif_image));
            case MessageType_Video:
                return String.format("[%s]",App.getInstanse().getString(R.string.video_text));
            case MessageType_Audio:
            case MessageType_Voice_Note:
                return String.format("[%s]",App.getInstanse().getString(R.string.voice_text));
            case MessageType_Document:
                return String.format("[%s]",App.getInstanse().getString(R.string.file_text));
            case MessageType_Location:
                return String.format("[%s]",App.getInstanse().getString(R.string.location_text));
            case MessageType_Pinned:
                return String.format("[%s]",App.getInstanse().getString(R.string.group_notification));
            case MessageType_Text_Screenshot:
                //某某于×月×日×时×分截屏了一次
                return screenshotDescription();
            case MessageType_Text_BeFriend:
                return beFriendDescription();
            case MessageType_Contact_Registered:
                return beContactRegistered();
            case MessageType_Contact:
                return contactDescription();
            default:
                return String.format("[%s]",App.getInstanse().getString(R.string.app_not_support_meesgae));
        }
    }

    private String screenshotDescription() {
        String who = null;
        if (sender_user_id() == UserInfo.getUserInfo().id) {
            who = App.getInstanse().getString(R.string.you_text);
        } else {
            who = UserInfo.userDisplayName(sender_user_id());
        }
        DateTime msgTime = new DateTime(date * 1000);
        return String.format(App.getInstanse().getString(R.string.sb_screenshot_at_st), who, msgTime.toString(App.getInstanse().getString(R.string.mm_dd_hh_mm_format)));
    }

    private String beFriendDescription() {
        if (sender_user_id() == UserInfo.getUserInfo().id) {
            return String.format(App.getInstanse().getString(R.string.you_added_so_firend), UserInfo.userDisplayName(chat_id));
        } else {
            return String.format(App.getInstanse().getString(R.string.so_added_you_friend), UserInfo.userDisplayName(chat_id));
        }
    }

    private String beContactRegistered() {
        return String.format(App.getInstanse().getString(R.string.contact_so_already_rg), UserInfo.userDisplayName(chat_id));
    }

    private String contactDescription() {
        String contactName = "";
        if(content!=null&&content.contact!=null){
            contactName = content.contact.displayName();
        }

        if (sender_user_id() == UserInfo.getUserInfo().id) {
            ChatInfo chat = TelegramManager.getTelegramManager().getTgData().chatInfo(chat_id);
            String targetName;
            if (chat != null&&chat.isGroup()) {
                targetName = chat.title;
            }else{
                targetName = UserInfo.userDisplayName(chat_id);
            }
            return MultiLanguageUtil.getInstance().isEnglish()?String.format(App.getInstanse().getString(R.string.you_recommended_so_to_so), contactName,targetName)
                    :String.format(App.getInstanse().getString(R.string.you_recommended_so_to_so), targetName,contactName);
        } else {
            return String.format(App.getInstanse().getString(R.string.so_recommended_so_to_you), UserInfo.userDisplayName(sender_user_id()),contactName);
        }
    }

    //文本消息内容
    public String textTypeContent;

    //视频语音通话消息
    public LocalCallInfo callInfo;

    public KickUserInfo kickUserInfo;

    //红包消息
    public RP_Msg rpInfo;
    public RP_Pick_Msg rpGotInfo;
    private RedPacketInfo redPacketInfo;
    public BurnAfterReadInfo barInfo;
    public RemittanceInfo tmInfo;

    public RedPacketInfo getRedPacketInfo() {
        return redPacketInfo;
    }

    public void setRedPacketInfo(RedPacketInfo redPacketInfo) {
        this.redPacketInfo = redPacketInfo;
    }

    //是否显示日期
    public boolean isShowDayText;

    //是否显示已读未读标志
    public boolean canShowReadFlag() {
        return messageType == TelegramManager.MessageType.MessageType_Text
                || messageType == TelegramManager.MessageType.MessageType_Text_New_Rp
                || messageType == TelegramManager.MessageType.MessageType_Video
                || messageType == TelegramManager.MessageType.MessageType_Photo
                || messageType == TelegramManager.MessageType.MessageType_Audio
                || messageType == TelegramManager.MessageType.MessageType_Voice_Note
                || messageType == TelegramManager.MessageType.MessageType_Document
                || messageType == TelegramManager.MessageType.MessageType_Location
                || messageType == TelegramManager.MessageType.MessageType_Animation;
    }

    public boolean isRemittedRemindType(){
        if(messageType == TelegramManager.MessageType.MessageType_Text
                &&content!=null
                &&content.text!=null
                &&!Common.isEmpty(content.text.entities)
                &&content.text.entities.get(0).type!=null
                && TextEntityType.RemiitedType.equals(content.text.entities.get(0).type.type)){
            return true;
        }
        return false;
    }

    public boolean isMessageCanRevoke(){
        if(isRemittedRemindType()){
            return false;
        }
        if(messageType== TelegramManager.MessageType.MessageType_Text_Got_Rp
                ||messageType== TelegramManager.MessageType.MessageType_Text_New_Rp
                ||messageType== TelegramManager.MessageType.MessageType_Text_Got_Tm
              ||messageType== TelegramManager.MessageType.MessageType_Text_New_Tm
                ||messageType== TelegramManager.MessageType.MessageType_Text_Refund_Tm){
            return false;
        }
        return true;
    }


    //是否本地消息
    public boolean isLocalMessage() {
        return messageType == TelegramManager.MessageType.MessageType_Text_AudioAVideo_Done;
    }

    //扩展消息解析
    public void parseTextToExMessage() throws NumberFormatException {
        String text = textTypeContent;
        if (!StringUtils.isEmpty(text) && text.startsWith("ct!")) {
            String[] list = text.split("!");
            if (list.length >= 5) {
                String md5 = list[1];
                int mainCode = Integer.parseInt(list[2]);
                int subCode = Integer.parseInt(list[3]);
                StringBuffer contentStr = new StringBuffer();
                for (int i = 4; i < list.length; i++) {
                    if (contentStr.length() > 0) {
                        contentStr.append("!");
                    }
                    contentStr.append(list[i]);
                }
                if (!StringUtils.isEmpty(md5)) {
                    String contentMd5 = Common.MD5(contentStr.toString());
                    if (md5.equalsIgnoreCase(contentMd5)) {
                        switch (mainCode) {
                            case TelegramManager.AudioAVideo_MessageType:
                                //音视频模块消息
                                parseTextToAudioAVideoMessage(contentStr.toString(), subCode);
                                break;
                            case TelegramManager.RP_MessageType:
                                //红包模块消息
                                parseTextToRpMessage(contentStr.toString(), subCode);
                                break;
                            case TelegramManager.BurnAfterRead_MessageType:
                                parseTextToBurnAfterReadMessage(contentStr.toString(), subCode);
                                break;
                            case TelegramManager.OtherEx_MessageType:
                                //其它扩展类消息
                                parseTextToOtherExMessage(contentStr.toString(), subCode);
                                break;
                            case TelegramManager.TM_MessageType:
                                //红包模块消息
                                parseTextToTmMessage(contentStr.toString(), subCode);
                                break;
                            case TelegramManager.Group_Keyword_MessageType:
                                parseTextToKickMessage(contentStr.toString(), subCode);
                                break;
                            default:
                                messageType = TelegramManager.MessageType.MessageType_Unkown;
                                break;
                        }
                    }
                }
            }
        }
    }

    private void parseTextToKickMessage(String contentStr, int subCode){
        switch (subCode) {
            case TelegramManager.Group_Keyword_MessageType_KICK:
                KickUserInfo userInfo = new Gson().fromJson(contentStr, KickUserInfo.class);
                textTypeContent = userInfo.displayDesc();
                kickUserInfo = userInfo;
                messageType = TelegramManager.MessageType.MessageType_Group_Kick;
                break;
            default:
                messageType = TelegramManager.MessageType.MessageType_Unkown;
                break;
        }
    }

    private void parseTextToAudioAVideoMessage(String contentStr, int subCode) {
        switch (subCode) {
            case TelegramManager.AudioAVideo_MessageType_Done: {
                LocalCallInfo callInfo = new Gson().fromJson(contentStr, LocalCallInfo.class);
                textTypeContent = callInfo.displayDesc();
                this.callInfo = callInfo;
                messageType = TelegramManager.MessageType.MessageType_Text_AudioAVideo_Done;
            }
            break;
            default:
                messageType = TelegramManager.MessageType.MessageType_Unkown;
                break;
        }
    }

    private void parseTextToBurnAfterReadMessage(String contentStr, int subCode) {
        if(subCode==TelegramManager.BurnAfterRead_MessageType_Done&&!TextUtils.isEmpty(contentStr)){
            BurnAfterReadInfo readInfo = new Gson().fromJson(contentStr, BurnAfterReadInfo.class);
            textTypeContent = readInfo.text;
            barInfo = readInfo;
        }
    }

    public long sender_user_id(){
        if(sender!=null){
            return sender.user_id;
        }else{
            return UserInfo.getUserInfo().id;
        }
    }

    public static final String TmRemindStartText = "你有一笔待接收的";
    public static final String TmRemindEndText = "转账";

    private void parseTextToTmMessage(String contentStr, int subCode) {
        switch (subCode) {
            case TelegramManager.TM_MessageType_New: {
                RemittanceInfo rp = new Gson().fromJson(contentStr, RemittanceInfo.class);
                textTypeContent = "[转账]";
                tmInfo = rp;
                messageType = TelegramManager.MessageType.MessageType_Text_New_Tm;
            }
            break;
            case TelegramManager.TM_MessageType_Got: {
                RemittanceInfo rp = new Gson().fromJson(contentStr, RemittanceInfo.class);
                textTypeContent = "[转账]已领取";
                tmInfo = rp;
                messageType = TelegramManager.MessageType.MessageType_Text_Got_Tm;
            }
            break;
            case TelegramManager.TM_MessageType_Refund:
            case TelegramManager.TM_MessageType_Refund_By_System:    {
                RemittanceInfo rp = new Gson().fromJson(contentStr, RemittanceInfo.class);
                textTypeContent = "[转账]已退还";
                tmInfo = rp;
                messageType = TelegramManager.MessageType.MessageType_Text_Refund_Tm;
            }
            break;
            case TelegramManager.TM_MessageType_Remind: {
                RemittanceInfo rp = new Gson().fromJson(contentStr, RemittanceInfo.class);
                textTypeContent = TmRemindStartText + TmRemindEndText;
                tmInfo = rp;
                content.text = TextInfo.buildRemittedRemindTextInfo(rp.remittanceId, TmRemindStartText, TmRemindEndText);
                messageType = TelegramManager.MessageType.MessageType_Text;
            }
            break;
            default:
                messageType = TelegramManager.MessageType.MessageType_Unkown;
                break;
        }
    }

    private void parseTextToRpMessage(String contentStr, int subCode) {
        switch (subCode) {
            case TelegramManager.RP_MessageType_New: {
                RP_Msg rp = new Gson().fromJson(contentStr, RP_Msg.class);
                textTypeContent = "[红包]";
                rpInfo = rp;
                messageType = TelegramManager.MessageType.MessageType_Text_New_Rp;
            }
            break;
            case TelegramManager.RP_MessageType_Got: {
                RP_Pick_Msg rp = new Gson().fromJson(contentStr, RP_Pick_Msg.class);
                textTypeContent = rp.description(sender_user_id());
                rpGotInfo = rp;
                messageType = TelegramManager.MessageType.MessageType_Text_Got_Rp;
            }
            break;
            default:
                messageType = TelegramManager.MessageType.MessageType_Unkown;
                break;
        }
    }

    private void parseTextToOtherExMessage(String contentStr, int subCode) {
        switch (subCode) {
            case TelegramManager.OtherEx_MessageType_Screenshot: {
                messageType = TelegramManager.MessageType.MessageType_Text_Screenshot;
            }
            break;
            case TelegramManager.OtherEx_MessageType_BeFriend: {
                messageType = TelegramManager.MessageType.MessageType_Text_BeFriend;
            }
            break;
            default:
                messageType = TelegramManager.MessageType.MessageType_Unkown;
                break;
        }
    }

    @SuppressLint("DefaultLocale")
    public static String getTextExMessage(String text, int mainCode, int subCode) {
        String md5 = Common.MD5(text);
        //^ct:([a-f\d]{32}|[A-F\d]{32}):(\d+):(\d+):([^$]+)
        return String.format("ct!%s!%d!%d!%s", md5, mainCode, subCode, text);
    }

    //本地通知使用
    public String notificationTitle() {
        ChatInfo chat = TelegramManager.getTelegramManager().getTgData().chatInfo(chat_id);
        if (chat != null) {
            if (chat.isGroup()) {
                return chat.title;
            } else {
                return UserInfo.userDisplayName(chat.userId());
            }
        } else {
            return App.getInstanse().getString(R.string.new_message);
        }
    }

    public String notificationContent() {
        ChatInfo chat = TelegramManager.getTelegramManager().getTgData().chatInfo(chat_id);
        if (chat != null) {
            if (chat.isGroup()) {
                return String.format("%s:%S", UserInfo.userDisplayName(sender_user_id()), toString());
            } else {
                return toString();
            }
        } else {
            return toString();
        }
    }



    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(this.id);
        dest.writeParcelable(this.sender, flags);
        dest.writeLong(this.chat_id);
        dest.writeLong(this.date);
        dest.writeByte(this.is_outgoing ? (byte) 1 : (byte) 0);
        dest.writeLong(this.reply_in_chat_id);
        dest.writeLong(this.reply_to_message_id);
        dest.writeInt(this.ttl);
        dest.writeDouble(this.ttl_expires_in);
        dest.writeParcelable(this.replyMessageInfo, flags);
        dest.writeByte(this.is_channel_post ? (byte) 1 : (byte) 0);
        dest.writeByte(this.contains_unread_mention ? (byte) 1 : (byte) 0);
        dest.writeParcelable(this.content, flags);
        dest.writeParcelable(this.reply_markup, flags);
        dest.writeParcelable(this.sending_state, flags);
        dest.writeInt(this.messageType == null ? -1 : this.messageType.ordinal());
        dest.writeString(this.textTypeContent);
        dest.writeParcelable(this.callInfo, flags);
        dest.writeParcelable(this.rpInfo, flags);
        dest.writeParcelable(this.rpGotInfo, flags);
        dest.writeParcelable(this.redPacketInfo, flags);
        dest.writeParcelable(this.barInfo, flags);
        dest.writeParcelable(this.tmInfo, flags);
        dest.writeByte(this.isShowDayText ? (byte) 1 : (byte) 0);
    }

    public void readFromParcel(Parcel source) {
        this.id = source.readLong();
        this.sender = source.readParcelable(MessageSendUser.class.getClassLoader());
        this.chat_id = source.readLong();
        this.date = source.readLong();
        this.is_outgoing = source.readByte() != 0;
        this.reply_in_chat_id = source.readLong();
        this.reply_to_message_id = source.readLong();
        this.ttl = source.readInt();
        this.ttl_expires_in = source.readDouble();
        this.replyMessageInfo = source.readParcelable(MessageInfo.class.getClassLoader());
        this.is_channel_post = source.readByte() != 0;
        this.contains_unread_mention = source.readByte() != 0;
        this.content = source.readParcelable(MessageContent.class.getClassLoader());
        this.reply_markup = source.readParcelable(ReplyMarkupInfo.class.getClassLoader());
        this.sending_state = source.readParcelable(MessageSendingState.class.getClassLoader());
        int tmpMessageType = source.readInt();
        this.messageType = tmpMessageType == -1 ? null : TelegramManager.MessageType.values()[tmpMessageType];
        this.textTypeContent = source.readString();
        this.callInfo = source.readParcelable(LocalCallInfo.class.getClassLoader());
        this.rpInfo = source.readParcelable(RP_Msg.class.getClassLoader());
        this.rpGotInfo = source.readParcelable(RP_Pick_Msg.class.getClassLoader());
        this.redPacketInfo = source.readParcelable(RedPacketInfo.class.getClassLoader());
        this.barInfo = source.readParcelable(BurnAfterReadInfo.class.getClassLoader());
        this.tmInfo = source.readParcelable(RemittanceInfo.class.getClassLoader());
        this.isShowDayText = source.readByte() != 0;
    }

    public MessageInfo() {
    }

    protected MessageInfo(Parcel in) {
        this.id = in.readLong();
        this.sender = in.readParcelable(MessageSendUser.class.getClassLoader());
        this.chat_id = in.readLong();
        this.date = in.readLong();
        this.is_outgoing = in.readByte() != 0;
        this.reply_in_chat_id = in.readLong();
        this.reply_to_message_id = in.readLong();
        this.ttl = in.readInt();
        this.ttl_expires_in = in.readDouble();
        this.replyMessageInfo = in.readParcelable(MessageInfo.class.getClassLoader());
        this.is_channel_post = in.readByte() != 0;
        this.contains_unread_mention = in.readByte() != 0;
        this.content = in.readParcelable(MessageContent.class.getClassLoader());
        this.reply_markup = in.readParcelable(ReplyMarkupInfo.class.getClassLoader());
        this.sending_state = in.readParcelable(MessageSendingState.class.getClassLoader());
        int tmpMessageType = in.readInt();
        this.messageType = tmpMessageType == -1 ? null : TelegramManager.MessageType.values()[tmpMessageType];
        this.textTypeContent = in.readString();
        this.callInfo = in.readParcelable(LocalCallInfo.class.getClassLoader());
        this.rpInfo = in.readParcelable(RP_Msg.class.getClassLoader());
        this.rpGotInfo = in.readParcelable(RP_Pick_Msg.class.getClassLoader());
        this.redPacketInfo = in.readParcelable(RedPacketInfo.class.getClassLoader());
        this.barInfo = in.readParcelable(BurnAfterReadInfo.class.getClassLoader());
        this.tmInfo = in.readParcelable(RemittanceInfo.class.getClassLoader());
        this.isShowDayText = in.readByte() != 0;
    }

    public static final Creator<MessageInfo> CREATOR = new Creator<MessageInfo>() {
        @Override
        public MessageInfo createFromParcel(Parcel source) {
            return new MessageInfo(source);
        }

        @Override
        public MessageInfo[] newArray(int size) {
            return new MessageInfo[size];
        }
    };
}
